﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Google.GData.Calendar;
using Google.GData.Client;

namespace ProgLab.CalendarSyncUtil
{
    /// <summary>
    /// 行事曆來源
    /// </summary>
    public abstract class CalendarSource
    {
        public List<CalendarItem> CalendarItems = new List<CalendarItem>();

        public abstract void Query(DateTime start, DateTime end);

        public abstract bool UpdateCalendar(ICalendarItem item);

        public abstract bool UpdateCalendar(ICalendarItem myItem, ICalendarItem srcItem);       
    }

    /// <summary>
    /// Google 行事曆
    /// </summary>
    public class GoogleCalendarSource : CalendarSource
    {
        public string URL = "";
        public string User = "";
        public string Password = "";

        protected CalendarService myService = new CalendarService("ProgLab-Google");
        
        public override void Query(DateTime start, DateTime end)
        {
            Query("https://www.google.com/calendar/feeds/default/private/full",
                start, end);
        }

        public override bool UpdateCalendar(ICalendarItem item)
        {
            throw new NotImplementedException();
        }

        public override bool UpdateCalendar(ICalendarItem myItem, ICalendarItem srcItem)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 查詢指定日曆的資料
        /// </summary>
        /// <param name="calendar"></param>
        public void Query(CalendarEntry calendar,DateTime start, DateTime end)
        {            
            Query("https://www.google.com/calendar/feeds/" +
                GetCalendarID(calendar.Id.Uri.Content) + "/private/full",
                start, end);
        }

        /// <summary>
        /// 查詢日曆的資料
        /// </summary>
        /// <param name="calendar"></param>
        public void Query( string uri, DateTime start, DateTime end)
        {
            this.CalendarItems.Clear();

            //Uri queryUri = new Uri("https://www.google.com/calendar/feeds/" + calendar.Id + "/private/full");
            // https://www.google.com/calendar/feeds/default/private/full
            EventQuery query = new EventQuery( uri );
            query.StartTime = start;
            query.EndTime = end;

            EventFeed result = myService.Query(query);

            foreach (EventEntry entry in result.Entries)
            {
                CalendarItems.Add(new GoogleCalendarItem(entry));
            }
        }

        public List<CalendarEntry> QueryAllCalendar()
        {
            myService.setUserCredentials(User, Password);

            CalendarQuery queryCalendar = new CalendarQuery();
            queryCalendar.Uri = new Uri("https://www.google.com/calendar/feeds/default/allcalendars/full");             
            CalendarFeed result = (CalendarFeed)myService.Query(queryCalendar);

            List<CalendarEntry> resultCalendar = new List<CalendarEntry>();
            foreach (CalendarEntry entry in result.Entries)
            {
                resultCalendar.Add(entry); 
            }

            return resultCalendar;
        }

        public CalendarEntry QueryCalendar( string calendarName )
        {
            List<CalendarEntry> allCalendar = QueryAllCalendar();
            foreach (CalendarEntry entry in allCalendar)
            {
                if (entry.Title.Text == calendarName)
                    return entry;
            }

            return null;

        }

        public static string GetCalendarID(string uri)
        {
            int pos = uri.LastIndexOf('/');
            if (pos >= 0)
            {
                return uri.Substring(pos + 1, uri.Length - pos - 1);
            }
            else
                return "";
        }

        public bool AddAppointment(EventEntry appointment,CalendarEntry calendar)
        {
            Uri addUri = new Uri("https://www.google.com/calendar/feeds/" +
                GetCalendarID(calendar.Id.Uri.Content) + "/private/full");
            EventEntry result = this.myService.Insert(addUri, appointment);
            return result != null;
        }
    }

}
